<?php

namespace App\Support;

use App\Models\Shop;
use Carbon\Carbon;
use Image;
use Cache;

class WechatSilentAuth
{
    public $redis;

    public $key = 'easywechat.common.access_token.';

    public function __construct()
    {
        $this->redis = Myredis::getInstance();
    }

    public function getToken($appID, $appSecret)
    {
        $key = $this->key.$appID;
        if (Cache::has($key)) {
            $access_token = Cache::get($key);
        } else {
            $apiUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appID . '&secret=' . $appSecret;
            $res = curlPost($apiUrl);
            $data = json_decode($res, true);
            $access_token = '';
            if ($data && isset($data['access_token'])) {
                $access_token = $data['access_token'];
                $expires_in = ($data['expires_in'] - 1500) / 60; // 过期时间
                Cache::put($key, $access_token, $expires_in);
            }
        }
        return $access_token;
    }

    public function getTokenAgain($appID, $appSecret)
    {
        $key = $this->key.$appID;
        $apiUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appID . '&secret=' . $appSecret;
        $res = curlPost($apiUrl);
        $data = json_decode($res, true);
        $access_token = '';
        if ($data && isset($data['access_token'])) {
            $access_token = $data['access_token'];
            $expires_in = ($data['expires_in'] - 1500) / 60; // 过期时间
            Cache::put($key, $access_token, $expires_in);
        }
        return $access_token;
    }

    public function getUserInfo($access_token, $openId, $appID = '', $appSecret = '')
    {
        $apiUrl = $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $access_token . "&openid=" . $openId;
        $res = curlGet($apiUrl);
        $data = json_decode($res, true);
        if (isset($data['errcode']) && $data['errcode'] == '40001') {
            $old_token = $access_token;
            $access_token = $this->getTokenAgain($appID,$appSecret);
            tolog([
                'time' => Carbon::now()->toDateTimeString(),
                'old_token' => $old_token,
                'new_token' => $access_token,
                'errcode' => $data['errcode'],
                'errmsg' =>  $data['errmsg'],
            ],'wechat.txt');
            $apiUrl = $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$access_token."&openid=".$openId;
            $res = curlGet($apiUrl);
            $data = json_decode($res, true);
        }
        return $data;
    }

    public function createQrCode($appId, $appSecret, $aid, $shop_id, $ext)
    {
        $result = [
            'status' => 1,
            'data' => '',
            'msg' => ''
        ];
        try {
            $access_token = $this->getToken($appId, $appSecret);
        } catch (\Exception $e) {
            $result['status'] = 0;
            $result['msg'] = '获取access_token失败';
            return $result;
        }
        $string = urlHome('Index', 'getEntrance', ['aid' => $aid, 'sid' => $shop_id], 2);

        try {
            $url = $this->multiQueryQrCodeUrl($access_token, 'permanent', $string,'', $appId, $appSecret);
        } catch (\Exception $e) {
            $result['status'] = 0;
            $result['msg'] = '获取qr_code_url失败';
            return $result;
        }
        $path = public_path() . '/uploads/qrImg';
        //检查文件夹是否存在，不存在则创建
        if (!is_dir($path)) {
            mkdir($path, 0755);
        }
        $baseImg = public_path() . '/uploads/share/' . $appId . '_1' . '.' . $ext;
        if (!file_exists($baseImg)) {
            $baseImg = public_path() . '/admin/images/qr_img_default.jpg';
        }
        $fileName = '/uploads/qrImg/' . $appId . '_qr' . '_' . $shop_id . '.' . $ext;
        if ($url) {
            try {
                $shop = (new Shop())->_getOneById($shop_id);
                $shopName = $shop ? $shop->shop_name : '';
                $res = $this->getFile($url, $baseImg, $shopName, public_path() . $fileName);
                if ($res) {
                    $result['data'] = $fileName . '?_=' . time();
                    return $result;
                }
            } catch (\Exception $e) {
                $result['status'] = 0;
                $result['msg'] = '转换图片失败';
                return $result;
            }
        } else {
            $result['status'] = 0;
            $result['msg'] = '获取ticket_url失败';
        }

        return $result;
    }

    // 多次请求获取ticket_url
    protected function multiQueryQrCodeUrl($access_token, $type, $string, $key = '', $appId = '', $appSecret = '')
    {
        $url = $this->getQrCodeUrl($access_token, $type, $string, $key);
        if ($url == 0) {
            $access_token = $this->getTokenAgain($appId, $appSecret);
            $url = $this->getQrCodeUrl($access_token, $type, $string, $key);
        }
        if (!$url) {
            $this->multiQueryQrCodeUrl($access_token, $string, $key, $appId, $appSecret);
        }
        return $url;
    }

    // 获取临时二维码
    public function getTempQrCode($appId, $appSecret, $key, $string)
    {
        $url = $this->redis->get($key);
        if ($url) {
            return $url;
        } else {
            $access_token = $this->getToken($appId, $appSecret);
            $url = $this->multiQueryQrCodeUrl($access_token, 'temp', $string, $key, $appId, $appSecret);
            return $url;
        }
    }

    // 获取ticket
    private function getQrCodeUrl($access_token, $type, $str, $key = '')
    {
        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $access_token;
        $qrData['action_info'] = ["scene" => ["scene_str" => $str]];
        $expire = 2592000;
        if ($type == 'permanent') {
            $qrData['action_name'] = "QR_LIMIT_STR_SCENE";
        } else {
            $qrData['action_name'] = 'QR_STR_SCENE';
            $qrData['expire_seconds'] = $expire;
        }
        $qrString = json_encode($qrData);
        $result = json_decode(curlPost($url, $qrString), 1);
        if ($result && isset($result['ticket']) && $result['ticket']) {
            $url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $result['ticket'];
            if ($type == 'temp') {
                $this->redis->setex($key, $expire, $url);
            }
            return $url;
        }
        if ($result && isset($result['errcode']) && $result['errcode'] == 40001) {
            return 0;
        }
        return false;
    }

    public function getFile($url, $baseImg, $shopName, $fileName)
    {
        $img = Image::make($url)->resize(480, 480);
        $img->save($fileName);
        if (file_exists($fileName)) {
            if (file_exists(public_path() . '/verify/zhttfs/EPSON 太角体.ttf') && $shopName) {
                Image::make($baseImg)->insert($fileName, 'center')->text($shopName, 540, 600, function ($font) { // 540,600 x,y坐标
                    $font->file(public_path() . '/verify/zhttfs/msyh.ttf'); // 字库
                    $font->size(80); //文字大小
                    $font->color('FF1217'); // 文字颜色
                    $font->align('center'); // 居中对齐
                    $font->valign('top'); // 向上垂直对齐
                })->save($fileName);
            } else {
                Image::make($baseImg)->insert($fileName, 'center')->save($fileName);
            }
            if (file_exists($fileName)) {
                return true;
            }
        }
        return false;
    }
}
